package com.ljt.base.utils

import android.annotation.SuppressLint
import android.util.Log


object LogUtil {

    private var isDebug = true
    private var SHOW_LINE_NUMBER_IN_LOG = isDebug// 是否在log中显示行号
    private val TAG = "com.jt.ktdemo.utils"
    //是否已初始化
    private var initFlag = true

    private val LOG_MAXLENGTH = 2000
    fun init(debugFlag: Boolean) {
        isDebug = debugFlag
        SHOW_LINE_NUMBER_IN_LOG = debugFlag
        initFlag = true
    }

    /**
     * 打印Log.w信息
     *
     * @param aPrintLogStr 打印信息字符串
     */
    fun w(aPrintLogStr: String) {
        LOG(TAG, aPrintLogStr, Log.WARN, false)
    }

    fun w(tag: String, aPrintLogStr: String) {
        LOG(tag, aPrintLogStr, Log.WARN, false)
    }

    fun i(tag: String, aPrintLogStr: String) {
        LOG(tag, aPrintLogStr, Log.INFO, false)
    }

    fun i(aPrintLogStr: String) {
        LOG(TAG, aPrintLogStr, Log.INFO, false)
    }

    fun callerI(aPrintLogStr: String) {
        LOG(TAG, aPrintLogStr, Log.INFO, true)
    }

    fun d(tag: String, aPrintLogStr: String) {
        LOG(tag, aPrintLogStr, Log.DEBUG, false)
    }

    fun d(aPrintLogStr: String) {
        LOG(TAG, aPrintLogStr, Log.DEBUG, false)
    }

    fun e(tag: String, aPrintLogStr: String) {
        LOG(tag, aPrintLogStr, Log.ERROR, false)
    }

    fun e(aPrintLogStr: String) {
        LOG(TAG, aPrintLogStr, Log.ERROR, false)
    }

    fun v(tag: String, aPrintLogStr: String) {
        LOG(tag, aPrintLogStr, Log.VERBOSE, false)
    }

    /**
     * @param tag        log的tag
     * @param content    log的内容
     * @param logType    log的类型,如Log.INFO,Log.DEBUG等
     * @param showCaller 是否显示调用者的方法名和行号等
     */
    @SuppressLint("DefaultLocale")
    private fun LOG(tag: String, content: String, logType: Int, showCaller: Boolean) {
        var content = content
        if (!initFlag) {
            Log.e("LogUtils", "LogUtil没有初始化，请先初始化后使用，如果未初始化Log将不会输出显示")
        }
        if (isDebug) {
            if (SHOW_LINE_NUMBER_IN_LOG) {
                val throwable = Throwable()
                val methodDepth = 2
                val stackTraceElements = throwable.stackTrace
                if (methodDepth < stackTraceElements.size) {
                    val element = stackTraceElements[methodDepth]
                    if (showCaller) {
                        if (methodDepth + 1 < stackTraceElements.size) {
                            val elementCaller = stackTraceElements[methodDepth + 1]
                            if (elementCaller != null && elementCaller.fileName != null) {
                                val callerClassName = elementCaller.fileName.substring(0, elementCaller.fileName.lastIndexOf("."))
                                val className = element!!.fileName.substring(0, element.fileName.lastIndexOf("."))
                                var loginfo = String.format("[%s.%s() (%s:%d)]", callerClassName, elementCaller.methodName, elementCaller.fileName, elementCaller.lineNumber)
                                loginfo = loginfo + "\n"
                                loginfo = loginfo + "    " + String.format("[%s.%s() (%s:%d)]%s", className, element.methodName, element.fileName, element.lineNumber, content)
                                content = loginfo
                            }
                        }
                    } else {
                        if (element != null && element.fileName != null) {
                            val className = element.fileName.substring(0, element.fileName.lastIndexOf("."))
                            val loginfo = String.format("[%s.%s() (%s:%d)]%s", className, element.methodName, element.fileName, element.lineNumber, content)
                            content = loginfo
                        }
                    }

                }
            }
            BH(tag, content, logType)
        }
    }

    fun BH(tag: String, msg: String, logType: Int) {  //信息太长,分段打印
        var msg = msg
        val max_str_length = 2001 - tag.length
        while (msg.length > max_str_length) {
            BHForI(tag, msg, logType)
            msg = msg.substring(max_str_length)
        }
        BHForI(tag, msg, logType)
    }

    fun BHForI(tag: String, content: String, logType: Int) {
        when (logType) {
            Log.INFO -> Log.i(tag, "===================>$content")
            Log.DEBUG -> Log.d(tag, "===================>$content")
            Log.ERROR -> Log.e(tag, "===================>$content")
            Log.WARN -> Log.w(tag, "===================>$content")
            Log.VERBOSE -> Log.v(tag, "===================>$content")
            else -> {
            }
        }//                    Log.v(tag,"===================>" + Constants.FOR_DEVELOPERS);
    }

}

